package com.balance.anole.erp.component;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ComboViewer;
import org.eclipse.jface.viewers.IElementComparer;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.swt.widgets.Composite;

import com.balance.anole.common.to.CodeLookTO;
import com.balance.anole.erp.common.provider.CodeLookComboLabelProvider;
import com.balance.anole.erp.common.service.BizCodesService;

/**
 * This class represent a ComboViewer which take CodeLookTO list as input.
 * Default label and content providers are created accordingly.
 * The element comparator compare two elements by checking the result of CodeLookTO.toString method.
 *
 * @author XP
 *
 */
public class CodeLookComboViewer extends ComboViewer {

	/**
	 * The default viewer element comparator.
	 * Refer to {@link ViewerComparator} for comparing algorithm.
	 */
//	private static final ViewerComparator viewerComparator = new ViewerComparator();

	private static final CodeLookElementComparator viewerComparator = new CodeLookElementComparator();

	public static final CodeLookTO EMPTY_SELECTION = new CodeLookTO("","");
	static {
		EMPTY_SELECTION.setCodeDesc("请选择");
	}

	/**
	 * Keep the code type value.
	 */
	private String codeType;

	/**
	 * Create a {@link CodeLookComboViewer}.
	 * Need initialize the input for the component.
	 * Default label provider: {@link CodeLookComboLabelProvider}
	 * Default content provider: {@link ArrayContentProvider}
	 *
	 * @param parent
	 * @param style
	 */
	public CodeLookComboViewer(Composite parent, int style) {
		super(parent, style);
		setViewerElementComparator();
		setProviderForCodeLook();
	}

	/**
	 * Create a {@link CodeLookComboViewer}. The viewer list will be created using the code type.
	 * Default label provider: {@link CodeLookComboLabelProvider}
	 * Default content provider: {@link ArrayContentProvider}
	 *
	 * @param codeType
	 * @param parent
	 * @param style
	 */
	public CodeLookComboViewer(String codeType,Composite  parent, int style) {
		this(parent, style);
		this.codeType = codeType;
		this.initInput(codeType);
	}

	public CodeLookComboViewer(String codeType, Composite parent, int style,boolean isClient) {
		this(parent, style);
		this.codeType = codeType;
		if(isClient){
			this.initInput(codeType,isClient);
		}else{
			this.initInput(codeType);
		}
	}

	/**
	 * Initialize the viewer list for the input code type.
	 *
	 * @param codeType
	 */
	public void initInput(String codeType){
		initInput(codeType,false);
	}

	public void initInput(String codeType,boolean isClient){
		List<CodeLookTO> codeList = new ArrayList<CodeLookTO>();
		codeList.add(EMPTY_SELECTION);
		if(isClient){
			codeList.addAll(BizCodesService.getInstance().getCodeLooksByCodeType(this.codeType,isClient));
		}else{
			codeList.addAll(BizCodesService.getInstance().getCodeLooksByCodeType(this.codeType));
		}
		this.setInput(codeList);
	}

	private void setViewerElementComparator(){
//		this.setComparator(viewerComparator);
		this.setComparer(viewerComparator);
	}

	private void setProviderForCodeLook(){
		this.setLabelProvider(new CodeLookComboLabelProvider());
		this.setContentProvider(new ArrayContentProvider());
	}

	public void setLayoutData(Object layoutData){
		this.getCombo().setLayoutData(layoutData);
	}

	static class CodeLookElementComparator implements IElementComparer{

		@Override
		public boolean equals(Object a, Object b) {
			if(!(a instanceof CodeLookTO) || !(b instanceof CodeLookTO)){
				return false;
			}
			CodeLookTO aCode = (CodeLookTO) a;
			CodeLookTO bCode = (CodeLookTO) b;

			String aCodeType = aCode.getCodeTypeId();
			String bCodeType = bCode.getCodeTypeId();

			String aCodeId = aCode.getCodeId();
			String bCodeId = bCode.getCodeId();

			if(aCodeType == null || aCodeId == null || bCodeType == null || bCodeId == null){
				return false;
			}

			if(aCodeType.equalsIgnoreCase(bCodeType) && aCodeId.equalsIgnoreCase(bCodeId)){
				return true;
			}

			return false;
		}

		@Override
		public int hashCode(Object element) {
			return element.hashCode();
		}

	}

}
